package net.csdn.business.common.oauth2.component;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Primary;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;


/**
 * @Desc:  本地加载token的ResourceServerTokenServices
 * @ClassName: CloudLocalResourceServerTokenServices
 * @Author: yourleige@163.com
 * @Date: 2022/9/26 11:47
 */
@Slf4j
@RequiredArgsConstructor
public class CloudLocalResourceServerTokenServices implements ResourceServerTokenServices {

	private final CustomRedisTokenStore customRedisTokenStore;

	//private final ClientDetailsService clientDetailsService;

	@Override
	public OAuth2Authentication loadAuthentication(String accessToken)
			throws AuthenticationException, InvalidTokenException {
		StopWatch stopWatch = new StopWatch();
		//此处可以屏蔽，只查询redis,redis不存在证明已经过期
		/*stopWatch.start("customJdbcTokenStore.readAccessToken");
		OAuth2AccessToken oauth2AccessToken = customJdbcTokenStore.readAccessToken(accessToken);
		stopWatch.stop();
		log.info("当前任务名：{},耗时：{}ms",stopWatch.getLastTaskName(),stopWatch.getLastTaskTimeMillis());
		if (oauth2AccessToken == null) {
			throw new InvalidTokenException("Invalid access token: " + accessToken);
		}
		else if (oauth2AccessToken.isExpired()) {
			customJdbcTokenStore.removeAccessToken(accessToken);
			throw new InvalidTokenException("Access token expired: " + accessToken);
		}*/
		stopWatch.start("customRedisTokenStore.readAuthentication");
		OAuth2Authentication oAuth2Authentication = customRedisTokenStore.readAuthentication(accessToken);
		stopWatch.stop();
		log.info("当前任务名：{},耗时：{}ms",stopWatch.getLastTaskName(),stopWatch.getLastTaskTimeMillis());
		if (oAuth2Authentication == null) {
			// in case of race condition
			throw new InvalidTokenException("Invalid access token: " + accessToken);
		}
		//校验client信息.可以注释掉，在client管理端，需要增加对修改client删除时，删除对应关联的token
		/*if (clientDetailsService != null) {
			String clientId = oAuth2Authentication.getOAuth2Request().getClientId();
			try {
				stopWatch.start("clientDetailsService.loadClientByClientId");
				clientDetailsService.loadClientByClientId(clientId);
				stopWatch.stop();
				log.info("当前任务名：{},耗时：{}ms",stopWatch.getLastTaskName(),stopWatch.getLastTaskTimeMillis());
			}
			catch (ClientRegistrationException e) {
				throw new InvalidTokenException("Client not valid: " + clientId, e);
			}
		}*/
		return oAuth2Authentication;
	}

	@Override
	public OAuth2AccessToken readAccessToken(String accessToken) {
		return customRedisTokenStore.readAccessToken(accessToken);
	}

}
